/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup TeeTrusted
 * @{
 *
 * @brief TEE（Trusted Excution Environment）可信执行环境API。
 *
 * 提供安全能力API，例如可信存储、加解密及可信时间等，用于可信应用程序开发。
 *
 * @since 20
 */

/**
 * @file tee_internal_se_api.h
 *
 * @brief 提供与TEE可信元素相关的API。
 *
 * @library NA
 * @kit TEEKit
 * @include <TEEKit/tee_internal_se_api.h>
 * @syscap SystemCapability.Tee.TeeClient
 * @since 20
 */

#ifndef TEE_INTERNAL_SE_API_H
#define TEE_INTERNAL_SE_API_H

#include "tee_defines.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 定义TEE_SEServiceHandle的结构体。
 *
 * @since 20
 */
struct __TEE_SEServiceHandle;

/**
 * @brief 定义TEE_SEReaderHandle的结构体。
 *
 * @since 20
 */
struct __TEE_SEReaderHandle;

/**
 * @brief 定义TEE_SESessionHandle的结构体。
 *
 * @since 20
 */
struct __TEE_SESessionHandle;

/**
 * @brief 定义TEE_SEChannelHandle的结构体。
 *
 * @since 20
 */
struct __TEE_SEChannelHandle;

/**
 * @brief 定义TEE_SEServiceHandle的指针类型。
 *
 * @since 20
 */
typedef struct __TEE_SEServiceHandle *TEE_SEServiceHandle;

/**
 * @brief 定义TEE_SEReaderHandle的指针类型。
 *
 * @since 20
 */
typedef struct __TEE_SEReaderHandle *TEE_SEReaderHandle;

/**
 * @brief 定义TEE_SESessionHandle的指针类型。
 *
 * @since 20
 */
typedef struct __TEE_SESessionHandle *TEE_SESessionHandle;

/**
 * @brief 定义TEE_SEChannelHandle的指针类型。
 *
 * @since 20
 */
typedef struct __TEE_SEChannelHandle *TEE_SEChannelHandle;

/**
 * @brief 定义最大ATR长度。
 *
 * @since 20
 */
#define ATR_LEN_MAX 32U

/**
 * @brief 定义最小AID长度。
 *
 * @since 20
 */
#define AID_LEN_MIN 5U

/**
 * @brief 定义最大AID长度。
 *
 * @since 20
 */
#define AID_LEN_MAX 16U

/**
 * @brief 定义逻辑通道的最大值。
 *
 * @since 20
 */
#define SE_LOGIC_CHANNEL_MAX 8U

/**
 * @brief 定义SCP03类型。
 *
 * @since 20
 */
#define TEE_SC_TYPE_SCP03 0x01

/**
 * @brief 定义字节长度。
 *
 * @since 20
 */
#define BYTE_LEN 8

/**
 * @brief 表示SE读取器的属性。
 *
 * @since 20
 */
typedef struct __TEE_SEReaderProperties {
    /** 如果读取器中存在SE，则值为true。 */
    bool sePresent;
    /** 如果该读取器仅通过TEE访问，则值为true。 */
    bool teeOnly;
    /** 如果在TEE中可以获取对SELECT的响应，则值为true。 */
    bool selectResponseEnable;
} TEE_SEReaderProperties;

/**
 * @brief 定义SE AID。
 *
 * @since 20
 */
typedef struct __TEE_SEAID {
    /** 应用程序的AID值。 */
    uint8_t *buffer;
    /** 应用程序AID的长度。 */
    uint32_t bufferLen;
} TEE_SEAID;

/**
 * @brief 枚举密钥的类型。
 *
 * @since 20
 */
typedef enum {
    /** 根据SCP02的基础密钥。 */
    TEE_SC_BASE_KEY = 0,
    /** 根据SCP02和SCP03的密钥集（密钥-MAC，密钥-ENC）。 */
    TEE_SC_KEY_SET = 1
} TEE_SC_KeyType;

/**
 * @brief 定义密钥集的引用。
 *
 * @since 20
 */
typedef struct __TEE_SC_KeySetRef {
    /** 密钥-ENC（静态加密密钥）。 */
    TEE_ObjectHandle scKeyEncHandle;
    /** 密钥-MAC（静态MAC密钥）。 */
    TEE_ObjectHandle scKeyMacHandle;
} TEE_SC_KeySetRef;

/**
 * @brief 枚举安全级别。
 *
 * @since 20
 */
typedef enum {
    /** 不应用任何保护。 */
    TEE_SC_NO_SECURE_MESSAGING = 0x00,
    /** 命令和响应APDU不加密。 */
    TEE_SC_AUTHENTICATE        = 0x80,
    /** 命令APDU应该进行MAC保护。 */
    TEE_SC_C_MAC               = 0x01,
    /** 响应APDU应该进行MAC保护。 */
    TEE_SC_R_MAC               = 0x10,
    /** 命令和响应APDU都应进行MAC保护。 */
    TEE_SC_CR_MAC              = 0x11,
    /** 命令APDU应该进行加密并进行MAC保护。 */
    TEE_SC_C_ENC_MAC           = 0x03,
    /** 响应APDU应该进行加密并进行MAC保护。 */
    TEE_SC_R_ENC_MAC           = 0x30,
    /** 命令和响应APDU都应进行加密并进行MAC保护。 */
    TEE_SC_CR_ENC_MAC          = 0x33,
    /** 命令APDU应该加密，且命令和响应APDU都应进行MAC保护。 */
    TEE_SC_C_ENC_CR_MAC        = 0x13
} TEE_SC_SecurityLevel;

/**
 * @brief 定义TEE_SC_AUTHENTICATE的别名。
 *
 * @since 20
 */
#define TEE_AUTHENTICATE TEE_SC_AUTHENTICATE

/**
 * @brief 表示SC卡密钥的引用。
 *
 * @since 20
 */
typedef struct __TEE_SC_CardKeyRef {
    /** SC卡密钥的密钥标识符。 */
    uint8_t scKeyID;
    /** SC卡密钥的密钥版本。 */
    uint8_t scKeyVersion;
} TEE_SC_CardKeyRef;

/**
 * @brief 表示与SC设备密钥相关的引用信息。
 *
 * @since 20
 */
typedef struct __TEE_SC_DeviceKeyRef {
    /** SC密钥的类型。 */
    TEE_SC_KeyType scKeyType;
    /**
     * @brief 包含SC密钥的具体信息。
     *
     * @since 20
     */
    union {
        /** SC基础密钥的句柄。 */
        TEE_ObjectHandle scBaseKeyHandle;
        /** SC密钥集的引用。 */
        TEE_SC_KeySetRef scKeySetRef;
    } __TEE_key;
} TEE_SC_DeviceKeyRef;

/**
 * @brief 定义SC的OID。
 *
 * @since 20
 */
typedef struct __TEE_SC_OID {
    /** OID的值。 */
    uint8_t *buffer;
    /** OID的长度。 */
    uint32_t bufferLen;
} TEE_SC_OID;

/**
 * @brief 表示关于SC的参数。
 *
 * @since 20
 */
typedef struct __TEE_SC_Params {
    /** SC类型。 */
    uint8_t scType;
    /** 由OID定义的SC类型。 */
    TEE_SC_OID scOID;
    /** SC的安全级别。 */
    TEE_SC_SecurityLevel scSecurityLevel;
    /** SC卡密钥的引用。 */
    TEE_SC_CardKeyRef scCardKeyRef;
    /** SC设备密钥的引用。 */
    TEE_SC_DeviceKeyRef scDeviceKeyRef;
} TEE_SC_Params;

/**
 * @brief 打开SE服务。
 *
 * @param se_service_handle [IN]指定SE服务的句柄。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ERROR_ACCESS_CONFLICT：由于冲突导致无法访问SE服务。
 * @since 20
 */
TEE_Result TEE_SEServiceOpen(TEE_SEServiceHandle *se_service_handle);

/**
 * @brief 关闭SE服务。
 *
 * @param se_service_handle [IN]指定SE服务的句柄。
 *
 * @since 20
 */
void TEE_SEServiceClose(TEE_SEServiceHandle se_service_handle);

/**
 * @brief 获取SE服务的可用读取器句柄。
 *
 * @param se_service_handle [IN]指定SE服务的句柄。
 * @param se_reader_handle_list [OUT]指定可用读取器的句柄列表。
 * @param se_reader_handle_list_len [OUT]指定句柄列表的长度。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ITEM_NOT_FOUND：无法找到输入的SE服务句柄。\n
 *         TEE_ERROR_SHORT_BUFFER：提供的缓冲区太小，无法存储读取器句柄。
 * @since 20
 */
TEE_Result TEE_SEServiceGetReaders(TEE_SEServiceHandle se_service_handle, TEE_SEReaderHandle *se_reader_handle_list,
                                   uint32_t *se_reader_handle_list_len);

/**
 * @brief 获取SE服务的可用读取器的属性。
 *
 * @param se_reader_handle [IN]指定SE读取器的句柄。
 * @param reader_properties [OUT]指定读取器的属性。
 *
 * @since 20
 */
void TEE_SEReaderGetProperties(TEE_SEReaderHandle se_reader_handle, TEE_SEReaderProperties *reader_properties);

/**
 * @brief 获取SE读取器的名称。
 *
 * @param se_reader_handle [IN]指定SE读取器的句柄。
 * @param reader_name [OUT]指定SE读取器的名称。
 * @param reader_name_len [OUT]指定读取器名称的长度。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ITEM_NOT_FOUND：无法找到输入的SE读取器句柄。\n
 *         TEE_ERROR_BAD_FORMAT：输入的se_reader_handle指向非法的读取器。\n
 *         TEE_ERROR_SHORT_BUFFER：reader_name_len太小，无法存储读取器名称。\n
 *         TEE_ERROR_SECURITY：检测到安全错误。
 * @since 20
 */
TEE_Result TEE_SEReaderGetName(TEE_SEReaderHandle se_reader_handle, char *reader_name, uint32_t *reader_name_len);

/**
 * @brief 在SE读取器和SE之间打开会话。
 *
 * @param se_reader_handle 指定SE读取器的句柄。
 * @param se_session_handle 指定会话句柄。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ITEM_NOT_FOUND：无法找到输入的SE读取器句柄。\n
 *         TEE_ERROR_COMMUNICATION：与SE通信失败。
 * @since 20
 */
TEE_Result TEE_SEReaderOpenSession(TEE_SEReaderHandle se_reader_handle, TEE_SESessionHandle *se_session_handle);

/**
 * @brief 关闭SE读取器和SE之间的会话。
 *
 * @param se_reader_handle 指定SE读取器的句柄。
 *
 * @since 20
 */
void TEE_SEReaderCloseSessions(TEE_SEReaderHandle se_reader_handle);

/**
 * @brief 获取SE ATR。
 *
 * @param se_session_handle 指定会话句柄。
 * @param atr 指定SE ATR。
 * @param atrLen 指定ATR的长度。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ERROR_SHORT_BUFFER：提供的缓冲区太小，无法存储 ATR。
 * @since 20
 */
TEE_Result TEE_SESessionGetATR(TEE_SESessionHandle se_session_handle, void *atr, uint32_t *atrLen);

/**
 * @brief 检查会话是否已关闭。
 *
 * @param se_session_handle 指定会话句柄。
 *
 * @return TEE_SUCCESS：会话已关闭或输入的句柄无效。\n
 *         TEE_ERROR_COMMUNICATION：会话状态无效。\n
 *         TEE_ERROR_BAD_STATE：会话已打开。
 * @since 20
 */
TEE_Result TEE_SESessionIsClosed(TEE_SESessionHandle se_session_handle);

/**
 * @brief 关闭SE会话。
 *
 * @param se_session_handle 指定会话句柄。
 *
 * @since 20
 */
void TEE_SESessionClose(TEE_SESessionHandle se_session_handle);

/**
 * @brief 关闭所有由SE会话指向的通道。
 *
 * @param se_session_handle 指定会话句柄。
 *
 * @since 20
 */
void TEE_SESessionCloseChannels(TEE_SESessionHandle se_session_handle);

/**
 * @brief 打开SE会话指向的基本通道。
 *
 * @param se_session_handle 指定会话句柄。
 * @param se_aid 指定SE AID。
 * @param se_channel_handle 指定SE通道句柄。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_STATE：会话已关闭。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ITEM_NOT_FOUND：无法找到输入的SE读取器句柄。\n
 *         返回其他值表示SE响应异常状态字。
 * @since 20
 */
TEE_Result TEE_SESessionOpenBasicChannel(TEE_SESessionHandle se_session_handle, TEE_SEAID *se_aid,
    TEE_SEChannelHandle *se_channel_handle);

/**
* @brief 打开SE会话指向的逻辑通道。
*
* @param se_session_handle 指定会话句柄。
* @param se_aid 指定SEAID。
* @param se_channel_handle 指定SE通道句柄。
*
* @return TEE_SUCCESS：操作成功。\n
*         TEE_ERROR_BAD_STATE：会话已关闭。\n
*         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
*         TEE_ITEM_NOT_FOUND：无法找到输入的SE读取器句柄。\n
*         返回其他值表示SE响应异常状态字。
* @since 20
*/
TEE_Result TEE_SESessionOpenLogicalChannel(TEE_SESessionHandle se_session_handle, TEE_SEAID *se_aid,
                                           TEE_SEChannelHandle *se_channel_handle);

/**
* @brief 关闭由通道句柄指向的通道。
*
* @param se_channel_handle 指定SE通道句柄。
*
* @since 20
*/
void TEE_SEChannelClose(TEE_SEChannelHandle se_channel_handle);

/**
 * @brief 选择由通道句柄指向的下一个SE服务。
 *
 * @param se_channel_handle 指定SE通道句柄。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数无效或SE模式错误。\n
 *         返回其他值表示SE响应异常状态字。
 * @since 20
 */
TEE_Result TEE_SEChannelSelectNext(TEE_SEChannelHandle se_channel_handle);

/**
 * @brief 获取在打开通道句柄时SE的SELECT命令响应。
 *
 * @param se_channel_handle 指定SE通道句柄。
 * @param response 指定SE的响应。
 * @param response_len 指定响应的长度。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数无效。\n
 *         TEE_ERROR_SHORT_BUFFER：提供的缓冲区太小，无法存储响应。
 * @since 20
 */
TEE_Result TEE_SEChannelGetSelectResponse(TEE_SEChannelHandle se_channel_handle, void *response,
                                          uint32_t *response_len);

/**
 * @brief 通过通道传输命令。
 *
 * @param se_channel_handle 指定SE通道句柄。
 * @param command 指定传输的命令。
 * @param command_len 指定命令的长度。
 * @param response 指定SE的响应。
 * @param response_len 指定响应的长度。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_COMMUNICATION：命令长度小于4。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数无效。\n
 *         TEE_ERROR_BAD_STATE：通道已关闭。
 * @since 20
 */
TEE_Result TEE_SEChannelTransmit(TEE_SEChannelHandle se_channel_handle, void *command, uint32_t command_len,
                                 void *response, uint32_t *response_len);

/**
 * @brief 打开基于输入通道句柄的SE安全通道。
 *
 * 此后，当调用TEE_SEChannelTransmit时，基于该句柄传输的所有APDU（加密/MAC保护）会自动根据定义的安全通道参数选项进行保护。\n
 * 目前仅支持SCP03。
 *
 * @param se_channel_handle 指定SE通道句柄。
 * @param sc_params 指定安全通道协议的参数引用。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_COMMUNICATION：与SE通信失败。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数无效或SE模式错误。\n
 *         TEE_ERROR_NOT_SUPPORTED：sc_params的参数不受支持。\n
 *         TEE_ERROR_MAC_INVALID：验证失败。
 * @since 20
 */
TEE_Result TEE_SESecureChannelOpen(TEE_SEChannelHandle se_channel_handle, TEE_SC_Params *sc_params);

/**
 * @brief 关闭基于输入通道句柄的SE安全通道。
 *
 * 由输入通道句柄指向的通道不会被关闭。\n
 * 它可以用于不安全的通信，但调用TEE_SEChannelTransmit时传输的APDU将不再是安全的。
 *
 * @param se_channel_handle 指定SE通道句柄。
 *
 * @since 20
 */
void TEE_SESecureChannelClose(TEE_SEChannelHandle se_channel_handle);

/**
 * @brief 获取由输入通道句柄指向的通道ID。
 *
 * @param se_channel_handle 指定SE通道句柄。
 * @param channel_id 指定SE通道ID。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数无效。
 * @since 20
 */
TEE_Result TEE_SEChannelGetID(TEE_SEChannelHandle se_channel_handle, uint8_t *channel_id);

#ifdef __cplusplus
}
#endif

#endif
/** @} */